package com.ky.pro.java.rpc.hd.app.service.impl;

import com.ky.pro.java.rpc.hd.app.service.IExchangeService;
import com.ky.pro.java.rpc.hd.common.api.DollarService;
import com.ky.pro.java.rpc.hd.common.api.RmbService;
import com.ky.pro.java.rpc.hd.common.web.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.hmily.annotation.HmilyTCC;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 完成支付后的操作：
 * 1. 更新订单状态
 * 2. 更新配餐状态
 */
@Service
@Slf4j
public class ExchangeServiceImpl implements IExchangeService {

    @DubboReference(version = "1.0.0")
    DollarService dollarService;

    @DubboReference(version = "1.0.0")
    RmbService rmbService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public void doExchange(long accountIdFrom, long accountIdTo, long dollarsToTransfer) {
        ResultBean<Boolean> dollarRet = dollarService.freezeAssets(accountIdFrom, dollarsToTransfer);
        if (!dollarRet.getData()) {
            throw new RuntimeException("美元账户冻结失败!");
        }
        ResultBean<Boolean> rmbRet = rmbService.freezeAssets(accountIdTo, dollarsToTransfer * 7);
        if (!rmbRet.getData()) {
            throw new RuntimeException("人民币账户冻结失败!");
        }
        log.info("账户冻结成功！");
    }

    @Transactional(rollbackFor = Exception.class)
    public void confirm(long accountIdFrom, long accountIdTo, long dollarsToTransfer) {
        // TODO: 幂等处理
        log.info("开始执行兑换操作...");
        ResultBean<Boolean> dollarRet = dollarService.exchangeToRmb(accountIdFrom, dollarsToTransfer);
        if (!dollarRet.isSuccess()) {
            throw new RuntimeException("美元兑换处理失败！");
        }
        ResultBean<Boolean> rmbRet =
                rmbService.exchangeToDollar(accountIdTo, dollarsToTransfer * 7);
        if (!rmbRet.isSuccess()) {
            throw new RuntimeException("人民币兑换处理失败！");
        }
        log.info("兑换操作完成！");
    }

    @Transactional(rollbackFor = Exception.class)
    public void cancel(long accountIdFrom, long accountIdTo, long dollarsToTransfer) {
        log.info("开始回滚操作...");
        ResultBean<Boolean> dollarRet = dollarService.freezeAssets(accountIdFrom, -dollarsToTransfer);
        if (!dollarRet.getData()) {
            throw new RuntimeException("美元账户冻结回滚失败!");
        }
        ResultBean<Boolean> rmbRet = rmbService.freezeAssets(accountIdTo, -dollarsToTransfer * 7);
        if (!rmbRet.getData()) {
            throw new RuntimeException("人民币账户冻结回滚失败!");
        }
        log.info("账户冻结回滚成功！");
    }

}
